/*
 * @(#)ThumbnailGenerator.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.framework.image;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;

import javax.media.jai.InterpolationNearest;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.swing.ImageIcon;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.framework.Utility;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.media.jai.codec.FileSeekableStream;

/**
  ThumbnailGenerator.java

  <p>This class is for generation of thumbnail.<p>

    @author          Rollo Chan
    @company         DCIVision Limited
    @creation date   04/01/2004
    @version         $Revision: 1.10.2.1 $
*/

public class ThumbnailGenerator {

  public static final String REVISION = "$Revision: 1.10.2.1 $";
  
  private static final Log log = LogFactory.getLog(ThumbnailGenerator.class);
  
  public static Hashtable hashExt = new Hashtable();
  static {
    hashExt.put("BMP", "Y");
    hashExt.put("GIF", "Y");
    hashExt.put("PNG", "Y");
    hashExt.put("JPG", "Y");
    hashExt.put("JPEG", "Y");
    hashExt.put("TIF", "Y");
    hashExt.put("TIFF", "Y");
  }

  /**
   * Reads an image in a file and creates a thumbnail in another file.
   *
   * @param orig The name of image file.
   * @param thumb The output stream of thumbnail.
   * @param maxDim The width and height of the thumbnail must be maxDim pixels or less.
   */
  public static void createThumbnail(String orig, OutputStream thumb, int maxDim) {
    try {
      // Get the image from a file.
      Image inImage = new ImageIcon(orig).getImage();

      // Determine the scale.
      double scale = (double)maxDim/(double)inImage.getHeight(null);
      if (inImage.getWidth(null) > inImage.getHeight(null)) {
        scale = (double)maxDim/(double)inImage.getWidth(null);
      }

      // Determine size of new image. One of them should equal maxDim.
      int scaledW = (int)(scale*inImage.getWidth(null));
      int scaledH = (int)(scale*inImage.getHeight(null));

      // Create an image buffer in which to paint on.
      BufferedImage outImage = new BufferedImage(scaledW, scaledH, BufferedImage.TYPE_INT_RGB);

      // Set the scale.
      AffineTransform tx = new AffineTransform();

      // If the image is smaller than the desired image size, don't bother scaling.
      if (scale < 1.0d) {
        tx.scale(scale, scale);
      }

      // Paint image.
      Graphics2D g2d = outImage.createGraphics();
      g2d.drawImage(inImage, tx, null);
      g2d.dispose();

      // JPEG-encode the image and write to file.
      JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(thumb);
      encoder.encode(outImage);
    } catch (IOException e) {
      log.error(e, e);
    }
  }

  /**
   * Reads an image in a file and creates a thumbnail in another file.
   *
   * @param orig The name of image file.
   * @param thumb The output stream of thumbnail.
   * @param maxDim The width and height of the thumbnail must be maxDim pixels or less.
   */
  public static void createPNGThumbnail(String orig, OutputStream thumb, int maxDim) {
    try {
    	RenderedOp image = null;
    	RenderedOp result = null;
    	int height = 0;
    	int width = 0;
    	
    	FileSeekableStream fss = new FileSeekableStream(orig);
      image = JAI.create("stream", fss);
      height = image.getHeight();
      width = image.getWidth();
    
      boolean tall = (height > width);
      float modifier = maxDim / (float) (tall ? height : width);
      if (modifier > 1.0F) {
        modifier = 1.0F;
      }
      ParameterBlock params = new ParameterBlock();
      params.addSource(image);
      params.add(modifier);//x scale factor
      params.add(modifier);//y scale factor
      params.add(0.0F);//x translate
      params.add(0.0F);//y translate
      params.add(new InterpolationNearest());//interpolation method
      result = JAI.create("scale", params);
    
      JAI.create("encode", result, thumb, "PNG", null);
    } catch (IOException e) {
      log.error(e, e);
    }
  }

  public static boolean isSupport(String sExt) {
    if (Utility.isEmpty(sExt)) {
      return(false);
    } else {
      return(hashExt.get(sExt.toUpperCase())!=null);
    }
  }

}

